import React, { useEffect, useState } from 'react'
import _ from 'lodash'
import { graphConfig, data, GraphConfig } from './config'
import G6 from '@antv/g6'

let graph

const TopologyEditor = () => {
  const [nodeConfig, setNodeConfig] = useState(null)
  const [isCreateEdge, setIsCreateEdge] = useState(false)
  useEffect(() => {
    createG6()
  }, [])
  const createG6 = () => {
    // 实例化 Grid 插件
    const grid = new G6.Grid()
    graph = new G6.Graph({
      ...GraphConfig,
      plugins: [grid],
      fitCenter: true,
    })
    graph.on('node:click', (e) => {
      // 先获取有click状态的所有节点
      const clickNodes = graph.findAllByState('node', 'click')
      clickNodes.forEach((cn) => {
        // 然后将所有当前是 click 状态的节点置为非 click 状态
        graph.setItemState(cn, 'click', false)
      })
      const nodeItem = e.item // 获取鼠标进入的节点元素对象(节点实例)
      // 设置节点的状态,状态的名称是随便起的
      // nodeStateStyles中状态的名也是随便起的,一般都是设置的状态,从而来改变样式
      graph.setItemState(nodeItem, 'click', true) // 设置当前节点的 click 状态为 true
      setNodeConfig(e.item._cfg.model)
    })
    graph.on('edge:mouseenter', (e) => {
      const nodeItem = e.item // 获取鼠标进入的节点元素对象
      graph.setItemState(nodeItem, 'hover', true) // 设置当前节点的 hover 状态为 true
    })
    graph.on('edge:mouseleave', (e) => {
      const nodeItem = e.item // 获取鼠标进入的节点元素对象
      graph.setItemState(nodeItem, 'hover', false) // 设置当前节点的 hover 状态为 true
    })

    graph.node((node) => {
      switch (node.type) {
        case 'rect':
          return {
            ...node,
            size: [100, 50],
          }
        default:
          return {
            ...node,
          }
      }
    })
    graph.edge((edge) => {
      return {
        ...edge,
        style: {
          endArrow: true,
          // startArrow: true,
        },
      }
    })
    graph.data(data) // 读取 Step 2 中的数据源到图上
    graph.render() // 渲染图
  }

  const onDragstart = (e, node) => {
    e.dataTransfer.setData('nodeProps', JSON.stringify(node))
  }

  const onDrop = (e) => {
    e.preventDefault()
    const nodeConfig = JSON.parse(e.dataTransfer.getData('nodeProps'))
    const nodeProps = {
      type: nodeConfig.id,
      img: nodeConfig.img,
    }
    const model = {
      id: 'node' + new Date().getTime(),
      label: 'node' + new Date().getTime(),
      address: 'cq',
      // clientX/clientY(距离视窗窗口左上角的坐标) 转换为 canvasX/canvasY(节点的渲染坐标 x/y )
      ...graph.getPointByClient(e.clientX, e.clientY),
      ...nodeProps,
    }

    graph.addItem('node', model)
  }
  const startLx = () => {
    if (!isCreateEdge) {
      graph.addBehaviors(
        {
          type: 'create-edge',
          trigger: 'drag',
        },
        'default'
      )
      graph.removeBehaviors('drag-node', 'default')

      setIsCreateEdge(true)
    } else {
      graph.addBehaviors('drag-node', 'default')
      graph.removeBehaviors('create-edge', 'default')
      setIsCreateEdge(false)
    }
  }
  const deleteNode = () => {
    graph.removeItem(nodeConfig.id)
  }

  return (
    <div className="TopologyEditor-layout">
      <div className="TopologyEditor-header">
        <button onClick={startLx}>开启/关闭连线功能</button>
        <button onClick={deleteNode}>删除节点</button>
      </div>
      <div className="TopologyEditor-content">
        <div className="TopologyEditor-left">
          {_.map(graphConfig, (item, key) => {
            return (
              <div
                id={item.id}
                key={item.id}
                draggable={item.draggable}
                {...item.props}
                onDragStart={(e) => onDragstart(e, item)}
              >
                {item.img ? (
                  <>
                    <img src={item.img} />
                    <div>{item.title}</div>
                  </>
                ) : (
                  item.title
                )}
              </div>
            )
          })}
        </div>
        <div
          className="TopologyEditor-center"
          id="TopologyEditor-center"
          onDrop={onDrop}
        ></div>
        <div className="TopologyEditor-right">
          <h1>节点信息</h1>
          <textarea
            rows="15"
            cols="20"
            value={JSON.stringify(nodeConfig)}
            onChange={() => {}}
          ></textarea>
        </div>
      </div>
    </div>
  )
}

export default TopologyEditor
